package com.cdream.basic.java8.io;

import cn.hutool.core.io.IoUtil;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

@FunctionalInterface
interface FileCopyRunner {
    /**
     * 文件复制
     *
     * @param source 源文件
     * @param target 目标文件
     */
    void copyFile(File source, File target);
}

/**
 * @author cdream
 * @date 2022/8/20
 */
public class FileCopyDemo {

    public static void main(String[] args) {
        FileCopyRunner noBufferStreamCopy = (source, target) -> {
            InputStream is = null;
            OutputStream os = null;
            try {
                is = new FileInputStream(source);
                os = new FileOutputStream(target);
                int res;
                while ((res = is.read()) != -1) {
                    os.write(res);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IoUtil.close(is);
                IoUtil.close(os);
            }

        };
        FileCopyRunner bufferStreamCopy = (source, target) -> {
            InputStream is = null;
            OutputStream os = null;
            try {
                is = new BufferedInputStream(new FileInputStream(source));
                os = new BufferedOutputStream(new FileOutputStream(target));
                byte[] buffer = new byte[1024];
                int res;
                while ((res = is.read(buffer)) != -1) {
                    os.write(buffer, 0, res);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IoUtil.close(is);
                IoUtil.close(os);
            }
        };
        FileCopyRunner nioBufferCopy = (source, target) -> {
            FileChannel is = null;
            FileChannel os = null;
            try {
                is = new FileInputStream(source).getChannel();
                os = new FileOutputStream(target).getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                while (is.read(buffer) != -1) {
                    buffer.flip();
                    while (buffer.hasRemaining()) {
                        os.write(buffer);
                    }
                    buffer.clear();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IoUtil.close(is);
                IoUtil.close(os);
            }
        };
        FileCopyRunner nioTransferCopy = (source, target) -> {
            FileChannel is = null;
            FileChannel os = null;
            try {
                is = new FileInputStream(source).getChannel();
                os = new FileOutputStream(target).getChannel();
                long transfer = 0;
                long size = is.size();
                while (transfer!=size) {
                    transfer += is.transferTo(transfer,size,os);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IoUtil.close(is);
                IoUtil.close(os);
            }
        };
    }


}

